"""
2.装饰器
python装饰器就是用于拓展原来函数功能的一种函数，这个函数的特殊之处在于它的返回值也是一个函数，
使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能
使用前提：
1.存在闭包
2.存在需要被装饰的函数
"""
#手动修饰装饰器函数
def decorator(func):
    # 传入的func是被装饰的函数
    def wrapper():
        print("验证密码")
        # 调用被装饰的函数
        func()
        print("记录日志")
    return wrapper
# def login():
#     print("登陆成功")
#
# decorator_func = decorator(login)
# decorator_func()

#使用@简化装饰器
@decorator  #作用：decorator_func = decorator(login)
def login():
    print("登陆成功")
login()

#带参数的装饰器
#如果原函数需要参数，装饰器的 wrapper 函数也需要接收这些参数。
def decorator(func):
    #传入的func是被装饰的函数
    def wrapper(*args, **kwargs):
        print("Before the function is called")
        #调用被装饰的函数
        result = func(*args, **kwargs)
        print("After the function is called")
        return result
    return wrapper

@decorator
def add(a, b):
    return a + b


# 输出:
# Before the function is called
# After the function is called
# 7

#装饰器本身也带参数：有时我们希望装饰器本身接受参数，这需要再套一层函数。
def decorator_with_args(prefix):
    #装饰器本身带有参数
    def decorator(func):
        #传入的func是被装饰的函数
        def wrapper(*args, **kwargs):
            print(f"{prefix}: Before the function is called")
            # 调用被装饰的函数
            result = func(*args, **kwargs)
            print(f"{prefix}: After the function is called")
            return result
        return wrapper
    return decorator

@decorator_with_args("LOG")
def multiply(a, b):
    return a * b


# 输出:
# LOG: Before the function is called
# LOG: After the function is called
# 12


if __name__ == '__main__':
    print(add(3, 4))

    print(multiply(3, 4))
